package com.lbd.commons;

import com.lbd.commons.exception.ControllerException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by WangYajie on 2016/9/12.
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private final Logger log = Logger.getLogger(this.getClass());

    /**
     * 其他异常处理
     *
     * @param e        异常
     * @param response 响应
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result exceptionHandler(Exception e, HttpServletResponse response) {
        log.warn("系统异常", e);
        response.setStatus(500);
        return new Result(ResultState.FAIL, "请联系管理员");

    }

    /**
     * 操作异常处理
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(value = ControllerException.class)
    @ResponseBody
    public Result controExceptionHandler(ControllerException e) {
        log.warn("操作异常", e);
        return new Result(ResultState.FAIL, e.getMessage());

    }

    /**
     * 数据校验错误处理器
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public Result bindExceptionHandler(BindException e) {
        BindingResult result = e.getBindingResult();
        if (result.hasErrors()) {
            log.warn("参数绑定异常", e);
            return new Result(ResultState.FAIL, "参数错误", getFieldErrorMessage(result));
        }
        return new Result(ResultState.FAIL);
    }

    /**
     * 拼装验证失败消息
     *
     * @param result 验证信息
     * @return
     */
    private static Map<String, String> getFieldErrorMessage(BindingResult result) {
        Iterator<ObjectError> it = result.getAllErrors().iterator();
        Map<String, String> map = new HashMap<>();
        while (it.hasNext()) {
            FieldError obj = (FieldError) it.next();
            map.put(obj.getField(), obj.getDefaultMessage());
        }
        return map;
    }

}
